#pragma once
#include "llog.hpp"
#include <arpa/inet.h>
#include <cerrno>
#include <cstring>
#include<iostream>
#include <netinet/in.h>
#include <string>
#include <sys/socket.h>

class Sock
{
public:
    Sock(){}
    int Socket()
    {
        int sock=socket(AF_INET, SOCK_DGRAM, 0);
        if(sock < 0)
        {
            logMessage(FATAL,"%d:%s",errno,strerror(errno));
            exit(2);
        }
        return sock;
    }
    void Bind(int sock,uint16_t port,std::string ip)
    {
        struct sockaddr_in server;
        socklen_t len=sizeof(server);
        server.sin_family=AF_INET;
        server.sin_port=htons(port);
        server.sin_addr.s_addr=inet_addr(ip.c_str());
        if(bind(sock,(struct sockaddr*)&server,sizeof(server)) < 0)
        {
            logMessage(FATAL, "%d:%s",errno,strerror(errno));
            exit(2);
        }
    }
    void Listen(int sock)
    {
        if(listen(sock, gbackLog) < 0)
        {
            logMessage(FATAL, "%d:%s",errno,strerror(errno))
            exit(2);
        }
        logMessage(NORMAL,"%d:%s",errno,strerror(errno));
    }
    //这里用于服务端
    //因为我这里收到了来自客户端的套接字以后还要必须将这些
    //信息发送给其他接口
    int Accept(int sock,uint16_t* port,std::string* ip="")
    {
        struct sockaddr_in client;
        socklen_t len=sizeof(client);
        int clientsock=0;
        clientsock = accept(sock, (struct sockaddr*)&client, &len);
        if(clientsock  < 0)
        {
            logMessage(FATAL, "%d:%s",errno,strerror(errno));
            exit(1);
        }
        if(port){*port=ntohs(client.sin_port);}
        if(ip){*ip=inet_ntoa(client.sin_addr);}
        return clientsock;
    }
    //针对客户端
    bool Connect(int sock,uint16_t& port,std::string& ip)
    {
        struct sockaddr_in server;
        memset(&server, 0, sizeof(server));
        server.sin_family=AF_INET;
        server.sin_port=htons(port);
        server.sin_addr.s_addr=inet_addr(ip.c_str());
        if(connect(sock, (struct sockaddr*)&server, sizeof(server)) == 0){
            return true;
        }
        else{
            return false;
        }
    }
    bool Connet2(int sock,uint16_t& port,std::string* ip)
    {
        struct sockaddr_in server;
        socklen_t len=sizeof(server);
        server.sin_family=AF_INET;
        server.sin_port=htons(port);
        server.sin_addr.s_addr=inet_addr(ip->c_str());
        int ret=connect(sock, (struct sockaddr*)&server, sizeof(server) == 0);
        if(ret == 0){
            return true;
        }
        else{
            return false;
        }
    }
    ~Sock(){

    }
private:
    const static int gbackLog=20;
};
// class Sock
// {
// public:
//     Sock(){}
//     int Socket()
//     {
//         int sock=socket(AF_INET, SOCK_DGRAM, 0);
//         if(sock < 0)
//         {
//             exit(1);
//         }
//         logMessage(NORMAL, "socket() done");
//         return sock;
//     }
//     // void Bind(int sock,uint16_t port,std::string ip="")
//     // {
//     //     struct sockaddr_in server;
//     //     bzero(&server,sizeof(server));
//     //     socklen_t len=sizeof(server);
//     //     server.sin_family=AF_INET;
//     //     server.sin_port=htons(port);
//     //     server.sin_addr.s_addr=inet_addr(ip.c_str());
//     //     //因为这里需要将地址和套接字想关联起来
//     //     if(bind(sock,(struct sockaddr*)&server,sizeof(server)) < 0)
//     //     {
//     //         exit(1);
//     //     }
//     // }
//     void Bind(int sock,uint16_t serverport,std::string serverip="")
//     {
//         struct sockaddr_in server;
//         memset(&server, 0, sizeof(server));
//         socklen_t len=sizeof(server);
//         server.sin_family=AF_INET;
//         server.sin_port=htons(serverport);
//         server.sin_addr.s_addr=inet_addr(serverip.c_str());
//         if(bind(sock,(struct sockaddr*)&server,len)  < 0)
//         {
//             exit(2);
//         }
//     }
//     void Listen(int sock)
//     {
//         //监听就是
//         struct sockaddr_in server;
//         if(listen(sock, gbackLog) < 0)
//         {
//             exit(2);
//         }
//     }
//     // void Bind(int sock)
//     // {
//     //     struct sockaddr_in client;
//     //     bzero(&client,sizeof(client));
//     //     socklen_t len=sizeof(client);
//     //     if(bind(sock, (struct sockaddr*)&client, len) < 0)
//     //     {
//     //         exit(1);
//     //     }
//     // }
// private:
//     const static int gbackLog=20;
// };
// class Sock
// {
// public:
//     Sock(){}
//     int Socket()
//     {
//         int sock=socket(AF_INET, SOCK_DCCP, 0);
//         if(sock < 0)
//         {
//             logMessage(FATAL,"%d:%s",errno,strerror(errno));
//             exit(1);
//         }
//         logMessage(NORMAL, "create socket success:%d",sock);
//         return sock;
//     }
//     void Bind(int sock,uint16_t port,std::string ip="0.0.0.0")
//     {
//         struct sockaddr_in server;
//         bzero(&server,sizeof(server));
//         server.sin_family=AF_INET;
//         server.sin_port=htons(port);
//         server.sin_addr.s_addr=inet_pton(sock, ip.c_str(), &server.sin_addr);
//         if(bind(sock,(struct sockaddr*)&server,sizeof(server)) < 0)
//         {
//             logMessage(FATAL, "bind() error",errno,strerror(errno));
//             exit(3);
//         }
//     }
//     //监听的时候是需要sock的
//     void Listen(int sock)
//     {
//         if(listen(sock,gbackLog) < 0)
//         {
//             logMessage(FATAL, "%d:%s",errno,strerror(errno));
//             exit(4);
//         }
//         logMessage(NORMAL, "init server success");
//     }
//     int Accept2(int sock,std::string* ip,uint16_t* port)
//     {
//         struct sockaddr_in server;
//         socklen_t len=sizeof(server);
//         int serversock=accept(sock, (struct sockaddr*)&server, &len);
//         if(serversock < 0)
//         {
//             logMessage(FATAL, "%d:%s",errno,strerror(errno));
//             exit(1);
//         }
//         if(port){*port=htons(server.sin_port);}
//         if(ip){*ip=inet_ntoa(server.sin_addr);}
//     }
//     int Accept(int sock,std::string* ip,uint16_t* port)
//     {
//         struct sockaddr_in server;
//         socklen_t len=sizeof(server);
//         int serversock=accept(sock, 
//         (struct sockaddr*)&server, &len);
//         if(serversock < 0)
//         {
//             logMessage(FATAL, "%d:%s",errno,strerror(errno));
//             exit(2);
//         }
//         if(port){
//             *port=ntohs(server.sin_addr);
//         }
//         else{
//             *ip=inet_ntoa(server.sin_addr);
//         }
//         return serversock;
//     }
//     bool Cannect(int sock,const std::string &server_ip,const std::uint16_t& server_port)
//     {
//         struct sockaddr_in server;
//         socklen_t len=sizeof(server);
//         server.sin_family=AF_INET;
//         server.sin_port=htons(server_port);
//         server.sin_addr.s_addr=inet_addr(server_ip.c_str());
//         if(connect(sock, (struct sockaddr*)&server, len) < 0)
//         {
//             logMessage(FATAL, "%d:%s",errno,strerror(errno));
//             exit(2);
//         }
//         else{
//             return false;
//         }
//     }
//     ~Sock(){

//     }
// private:
//     const static int gbackLog=20;
// };
// // class Sock
// // {
// // public:
// //     Sock(){}
// //     int Socket()
// //     {
// //         int sock=socket(AF_INET, SOCK_DGRAM, 0);
// //         if(sock < 0)
// //         {
// //             logMessage(FATAL, "%d:%s",errno,strerror(errno));
// //             exit(2);
// //         }
// //         return sock;
// //     }
// //     int Sock2()
// //     void Bind(int sock,uint16_t port,std::string ip="0.0.0.0")
// //     {
// //         struct sockaddr_in local;
// //         bzero(&local,sizeof(local));
// //         local.sin_family=AF_INET;
// //         local.sin_addr.s_addr=inet_pton(sock, ip.c_str(),&local.sin_addr);
// //         local.sin_port=htons(port);
// //         if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0)
// //         {
// //             logMessage(FATAL, "%d:%s",errno,strerror(errno));
// //             exit(3);
// //         }
// //     }
// //     void Listen(int sock)
// //     {
// //         if(listen(sock, gbackLog) < 0)
// //         {
// //             logMessage(FATAL, "%d:%s",errno,strerror(errno));
// //             exit(2);
// //         }
// //     }
// //     //这里全都是输出型参数
// //     //将来这里的参数还可以共他人所用
// //     int Accept(int sock,std::string* ip,uint16_t* port)
// //     {
// //         struct sockaddr_in server;
// //         socklen_t len=sizeof(server);
// //         int serversock=accept(sock, (struct sockaddr*)&server, &len);
// //         if(serversock < 0)
// //         {
// //             logMessage(FATAL, "%d:%s",errno,strerror(errno));
// //             exit(2);            
// //         }
// //         if(port){
// //             *port=ntohs(server.sin_port);
// //         }
// //         if(ip){
// //             *ip=inet_ntoa(server.sin_addr);
// //         }
// //         return serversock;
// //     }
// //     bool Connect(int sock,const std::string &server_ip,const uint16_t& server_port)
// //     {
// //         struct sockaddr_in server;
// //         memset(&server, 0, sizeof(server));
// //         server.sin_family=AF_INET;
// //         server.sin_port=htons(server_port);
// //         server.sin_addr.s_addr=inet_addr(server_ip.c_str());
// //         if(connect(sock, (struct sockaddr*)&server, sizeof(server)) == 0)
// //         {
// //             return true;
// //         }
// //         else{
// //             return false;
// //         }
// //     }
// //     ~Sock(){

// //     }
// // private:
// //     const int gbackLog=20;
// // };
